package com.itboye.core.utils;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.Spanned;
import android.util.Log;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.itboye.core.exceptions.CodeErrorException;

public class XJsonRequest<T> extends Request<T> {

	private Type expectReturnType;// 期望返回参数的类
	private XRequestListener<T> listener;

	private XErrorListener errorListener;
	private Map<String, String> headers = new HashMap<String, String>();
	private int method = Method.DEPRECATED_GET_OR_POST;
	private Map<String, String> params = new HashMap<String, String>();
	/**
	 * 处理code！=0时的特殊情况！！！！！！
	 * 
	 */
	private boolean isCodeZero = true;

	/**
	 * 
	 * 
	 * @param method
	 * @param url
	 * @param listener
	 * @param errlistener
	 *            请求异常，失败，code！=0 时会调用，</br></br>
	 *            code!=0时，onErrorResponse(Exception exception,int code,String
	 *            msg)中 exception
	 *            是CodeErrorException，code为服务器返回的状态码，msg为服务端返回的出错信息（data中字符串）
	 *            </br></br> json解析失败时，onErrorResponse(Exception exception,int
	 *            code,String msg)中 exception 是JSONException，code为0，msg为null
	 *            </br></br> 其他异常时 onErrorResponse(Exception exception,int
	 *            code,String msg)中 exception 是Exception，code为0，msg为null
	 */
	public XJsonRequest(String url, XRequestListener<T> listener,
			XErrorListener errlistener) {

		super(Method.POST, url, null);
		this.listener = listener;
		this.errorListener = errlistener;
	}

	/**
	 * 
	 * @param method
	 * @param url
	 * @param listener
	 * @param errlistener
	 *            请求异常，失败，code！=0 时会调用，</br></br>
	 *            code!=0时，onErrorResponse(Exception exception,int code,String
	 *            msg)中 exception
	 *            是CodeErrorException，code为服务器返回的状态码，msg为服务端返回的出错信息（data中字符串）
	 *            </br></br> json解析失败时，onErrorResponse(Exception exception,int
	 *            code,String msg)中 exception 是JSONException，code为0，msg为null
	 *            </br></br> 其他异常时 onErrorResponse(Exception exception,int
	 *            code,String msg)中 exception 是Exception，code为0，msg为null
	 */
	public XJsonRequest(int method, String url, XRequestListener<T> listener,
			XErrorListener errlistener) {

		super(method, url, null);

		this.listener = listener;
		this.errorListener = errlistener;
	}

	@Override
	protected void deliverResponse(T response) {
		if (null != listener) {
			try {
				listener.onResponse(response);
			} catch (Exception e) {

				e.printStackTrace();
			}
		}
	}

	@Override
	public void deliverError(VolleyError error) {
		super.deliverError(error);

		if (errorListener != null && isCodeZero) {
			try {
				errorListener.onErrorResponse(error, "0", null);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	public XJsonRequest<T> addHeader(String k, String value) {
		headers.put(k, value);
		return this;
	}

	@Override
	public Map<String, String> getHeaders() throws AuthFailureError {
		return headers;
	}

	public XJsonRequest<T> setMethod(int method) {
		this.method = method;
		return this;
	}

	@Override
	public int getMethod() {
		return method;
	}

	public XJsonRequest<T> addParam(String k, String value) {
		params.put(k, value);
		return this;
	}

	public XJsonRequest<T> addParams(Map<String, String> params) {
		this.params.putAll(params);
		return this;
	}

	@Override
	protected Map<String, String> getParams() throws AuthFailureError {

		return params;
	}

	public Type getExpectReturnType() {
		return expectReturnType;
	}

	public void setExpectReturnType(Type expectReturnType) {
		this.expectReturnType = expectReturnType;
	}

	// 该方法中gson解析可能需要调整
	@Override
	protected Response<T> parseNetworkResponse(NetworkResponse response) {
		String parsed;
		try {
			parsed = new String(response.data,
					HttpHeaderParser.parseCharset(response.headers));
		} catch (UnsupportedEncodingException e) {
			parsed = new String(response.data);
		}

		try {
			if (listener == null) {
				return null;
			}

			JSONObject obj = new JSONObject(parsed);
			System.out.println("数据" + obj.toString());
			String type = obj.getString("type");
			String resultData = obj.getString("data");
			if (type.equals("E")) {
				return Response.error(new VolleyError("服务器出错!"));
			}

			if (this.getExpectReturnType() == null) {
				return Response.error(new VolleyError("必须指定返回数据类型"));
			}

			// Type typeClass1 = listener.getClass().getGenericSuperclass();
			// if (!(typeClass1 instanceof ParameterizedType) ){
			// return Response.error(new VolleyError("返回参数异常!"));
			// }
			//
			// Type actualType = ((ParameterizedType)
			// typeClass1).getActualTypeArguments()[0];

			parsed = DataEncryptionUtil.decodeData(resultData);
			JSONObject decodeJsonObj = new JSONObject(parsed);
			printLogDetail("decodeResponse", JsonFormat.format(parsed));

			String code = decodeJsonObj.getString("code");
			if (!code.equals("0")) {
				if (errorListener != null) {
					String data = decodeJsonObj.getString("data");
					if (data != null) {
						handlerError(new CodeErrorException(data), code, data);
					} else {
						handlerError(new CodeErrorException("请求失败!"), code,
								data);
					}
				}
				return Response.error(new VolleyError("请求异常!"));
			}

			resultData = decodeJsonObj.getString("data");
			// printLogDetail("print",resultData);
			Log.e("e", resultData);
			Gson gson = new GsonBuilder()
					.setFieldNamingPolicy(
							FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
					.registerTypeAdapter(Spanned.class, new String2Spanned())
					.create();
			System.out.println("服务器数据" + resultData);
			@SuppressWarnings("unchecked")
			T res = (T) gson.fromJson(resultData, this.expectReturnType);

			if (null != res) {
				return Response.success(res,
						HttpHeaderParser.parseCacheHeaders(response));
			}

		} catch (JSONException e) {

			e.printStackTrace();
		}

		return Response.error(new VolleyError("请求异常!"));

	}

	/**
	 * 输出完整json，防止一次输出过多时显示不完整问题
	 * 
	 * @param tag
	 * @param json
	 */
	private void printLogDetail(String tag, String json) {

		try {
			int len = 3500;
			int position = 0;

			while (json.length() - position > len) {
				for (int i = 0; i < json.length() - position - len; i++) {
					if (json.charAt(position + len + i) == '\n') {
						DebugLog.v(tag,
								json.substring(position, position + len + i));

						position = position + len + i + 1;
						break;
					}
				}

			}
			DebugLog.v(tag, json.substring(position, json.length()));

		} catch (Exception e) {
			DebugLog.v(tag, json);
		}

	}

	private void handlerError(final Exception exception, final String code,
			final String msg) {

		isCodeZero = false;
		// errorListener.onErrorResponse(exception, code, msg);

		new Handler(Looper.getMainLooper()) {
			@Override
			public void handleMessage(Message m) {
				errorListener.onErrorResponse(exception, code, msg);
				super.handleMessage(m);
				try {
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}.sendEmptyMessage(0);

	}

}
